Next | Prev | Up | Top | Contents | Index
Registering the Interrupt Handler
When the program is ready to start operations, it registers its ULI handler. The ULI handler is a function that matches the prototype
void function_name(void *arg);
The registration function takes arguments with the following purposes:
- the file descriptor of the device special file
- four arguments related to the ULI handler:
- the address of the handler function
- an argument value to be passed to the handler on each interrupt--typically a pointer to a work area that is unique to the interrupting device, supposing the program is using more than one device
- the size, and an optional address, of memory to be used as stack space when calling the handler
- a count of semaphores to be allocated for use with this interrupt
You can ask the ULI support to allocate a stack space by passing a null pointer for the stack argument. When the ULI handler is as simple a function as it normally is, the default stack size of 1024 bytes is ample.
The semaphores are allocated and maintained by the ULI support. They are used to coordinate between the program process and the interrupt handler, as discussed under "Interacting With the Handler". You should specify one semaphore for each independent process that can wait for interrupts from this handler. Normally one semaphore is sufficient.
The returned value is a handle that is used to identify this interrupt in other functions. Once registered, the ULI handler remains registered until the program terminates (there is no function for un-registration).
Registering an External Interrupt Handler
The ULI_register_ei() function takes the arguments described in the preceding topic. Once it has successfully registered your handler, all external interrupts are directed to that handler.
It is important to realize that, so long as a ULI handler is registered, none of the other interrupt-reporting features supported by the external interrupt device driver (see Chapter 6, "Control of External Interrupts" and the ei(7) reference page) operate any more. These restrictions include the facts that:
- The per-process external interrupt queues are not updated.
- Signals requested by ioctl(EIIOCSETSIG) are not sent.
- Calls to ioctl(EIIOCRECV) sleep until they are interrupted by a timeout, a signal, or because the program using ULI terminated and an interrupt arrived.
- Calls to the library function eicbusywait() do not terminate.
Clearly you should not use ULI for external interrupts when there are other programs running that also use them.
Registering a VME Interrupt Handler
The ULI_register_vme() function takes two additional arguments:
- the interrupt level that the device uses.
- a word that contains, or receives, an interrupt vector number
The interrupt level used by a device is normally set by hardware and documented in the VECTOR line that defines the device (see "Learning VME Device Addresses").
Some VME devices have a fixed interrupt vector number; others are programmable. You pass a fixed vector number to the function. If the number is programmable, you pass 0, and the function allocates a number. You must then use PIO to program the vector number into the device.
Next | Prev | Up | Top | Contents | Index